﻿
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Chemistry.Models;
using System.Threading;
using System.Text.RegularExpressions;
using OPCAutomation;
using GLCommon;

namespace Chemistry.WorkFlow
{
    /// <summary>
    /// 苯酚异丁烯烷基化自控流程
    /// </summary>
    public class Alkylation : FlowBaseAll
    {
        #region 字段
        private int _sleepfast = 500;
        private int _sleepSlow = 1000;
        private static int _relay_command ;
         double _phenol_value ;
         double _pressure_value ;
         double _temperature_value = 22;
         double _flow_value = 10;

        bool _isgetoverstate1 = false;
        bool _isgetoverstate2 = false;
        double _phenol_increment = 10;
        double _phenol_decrement = 10;
        double _temperature_increment = 2;
        double _temperature_decrement = 1;
        double _pressure_increment;
        double _pressure_decrement;
        double _flow_crement = 1;

        //命令
        private Tools.Tool.FlowCommand _flowcommand;
        string _switch1 = string.Empty;
        string _switch2 = string.Empty;
        string _prefix1 = string.Empty;
        string _prefix2 = string.Empty;
        string _llcmd = string.Empty;
        string _ywcmd = string.Empty;
        string _ylcmd = string.Empty;
        string _wdcmd = string.Empty;
        string _aicmd = string.Empty;
        string _relaycmd = string.Empty;
        int _warning1number = 0;
        int _warning2number = 0;
        int _fognumber = 0;
        int _stirnumber;
        //步骤标记
        static bool _isreplaceN2_over = false;
        int _replacecount = 1;
        bool _canopenempty = false;

         int open = 1; //0-48
         int close = 0; //1=49

        #endregion

        #region 组态开关状态
        /// <summary>
        /// 苯酚进料阀
        /// </summary>
        static bool _valveInPhenol_State = false;//苯酚进料阀
        /// <summary>
        /// 苯酚放料阀
        /// </summary>
         bool _valveOutPhenol_State = false;//苯酚放料阀
         bool _valveN2_State = false;
         bool _valveEmpty_State = false;
         bool _valveAutoEmpty_State = false;
         bool _valveInCold_State = false;
         bool _valveInHot_State = false;
        /// <summary>
        /// 异丁烯进料阀
        /// </summary>
         bool _valveIsobutene_State = false;
        /// <summary>
        /// 紧急切断阀
        /// </summary>
         bool _valveICutoff_State = false;
        /// <summary>
        /// 放料阀
        /// </summary>
         bool _valveDischarge_State = false;
        /// <summary>
        /// 搅拌
        /// </summary>
         bool _valveStir_State = false;
        /// <summary>
        /// 急停按钮状态
        /// </summary>
         bool _valveStop_State = false;

        #endregion

        #region OPCItem

        //阀门
        OPCItem ValveInPhenol_item;
        OPCItem ValveOutPhenol_item;
        OPCItem ValveN2_item;
        OPCItem ValveEmpty_item;
        OPCItem ValveAutoEmpty_item;
        OPCItem ValveInCold_item;
        OPCItem ValveInHot_item;
        OPCItem ValveIsobutene_item;
        OPCItem ValveICutoff_item;
        OPCItem ValveDischarge_item;
        OPCItem ValveStir_item;
        OPCItem ValveStop_item;

        //管道
        OPCItem FlowEmpty_item;
        OPCItem FlowInCold_item;
        OPCItem FlowInHot_item;
        OPCItem FlowInPhenol_item;
        OPCItem FlowIsObutene_item;
        OPCItem FlowInN2_item;
        OPCItem FlowOutPhenol_item;
        OPCItem FlowOutSpices_item;

        //label
        OPCItem LabelLevel_item;
        OPCItem LabelOxygen_item;
        OPCItem LabelPressure_item;
        OPCItem LabelTemperature_item;
        OPCItem LabelFlow_item;


        //闪烁
        OPCItem FlashCatalyst_item;
        OPCItem FlashStir_item;
        OPCItem FlashPressure_item;
        OPCItem FlashTemperature_item;
        OPCItem FlashWarning_item;
        #endregion

        #region 初始化
        public Alkylation(OPCServer opcserver, SerialPort port , bool isinner)
        {
            _opcServer = opcserver;
            _serialPort = port;
            Isinner = isinner;

            InitFiled();
            InitOPC();
            InitOPCItem();
            InitSignal();
        }

        public Alkylation(OPCServer opcserver, SerialPort port, bool isinner , bool isslow)
        {
            _opcServer = opcserver;
            _serialPort = port;
            Isinner = isinner;
            IsExamSpeed = isslow;

            InitFiled();
            InitOPC();
            InitOPCItem();
            InitSignal();
        }

        private async Task InitServerData()
        {
            _details = await GetDetailList(GetType().Name);
        }

        private void InitSignal()
        {
            if (Isinner)
            {
                open = 1;
                close = 0;
                ListenSignal();
                
            }
            else
            {
                InitFlowCommandData();
                _serialPort.DataReceived += _serialPort_DataReceived;
                InitOpcItemWithSerialPort();
                ListenSerialPort();
                open = 48;
                close = 49;
            }
        }

        private void InitFiled()
        {
            _relay_command = 0;
            _phenol_value = 500;//500---0
            _pressure_value = 0;
            _temperature_value = 22;
            _flow_value = 0;

            _isgetoverstate1 = false;
            _isgetoverstate2 = false;
            _phenol_increment = 10;
            _phenol_decrement =10;
            _temperature_increment = 2;
            _temperature_decrement = 1;
            _pressure_increment = 0.02;
            _pressure_decrement = 0.04;
            _flow_crement = 1;
        }

        private void InitFlowCommandData()
        {
            _flowcommand = Tools.Tool.GetFlowCommand(this.GetType().Name);
            _switch1 = _flowcommand.Items.SingleOrDefault(i => i.Name == "switch1").Value;
            _switch2 = _flowcommand.Items.SingleOrDefault(i => i.Name == "switch2").Value;
            _prefix1 = _flowcommand.Items.SingleOrDefault(i => i.Name == "prefix1").Value;
            _prefix2 = _flowcommand.Items.SingleOrDefault(i => i.Name == "prefix2").Value;
            _llcmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "llcmd").Value;
            _ywcmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "ywcmd").Value;
            _ylcmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "ylcmd").Value;
            _wdcmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "wdcmd").Value;
            _aicmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "aicmd").Value;
            _relaycmd = _flowcommand.Items.SingleOrDefault(i => i.Name == "relaycmd").Value;
            _warning1number = int.Parse(_flowcommand.Items.SingleOrDefault(i => i.Name == "warning1").Value);
            _warning2number = int.Parse(_flowcommand.Items.SingleOrDefault(i => i.Name == "warning2").Value);
            _fognumber = int.Parse(_flowcommand.Items.SingleOrDefault(i => i.Name == "fog").Value);
            _stirnumber = int.Parse(_flowcommand.Items.SingleOrDefault(i => i.Name == "stir").Value);
        }

        private void InitOpcItemWithSerialPort()
        {
            SpFlowValue(_flow_value);                       
            SpTemperatureValue(_temperature_value);
            SpPressureValue(_pressure_value);
            SPWriteTool(_relay_command);
            SPYWValue(_phenol_value);
        }

        private void InitOPCItem()
        {
            //阀门
            ValveInPhenol_item = GetItem(FiledName.ValveInPhenol); ValveInPhenol_item.Close();
            ValveOutPhenol_item = GetItem(FiledName.ValveOutPhenol); ValveOutPhenol_item.Close();
            ValveN2_item = GetItem(FiledName.ValveN2); ValveN2_item.Close();
            ValveEmpty_item = GetItem(FiledName.ValveEmpty); ValveEmpty_item.Open();
            ValveAutoEmpty_item = GetItem(FiledName.ValveAutoEmpty); ValveAutoEmpty_item.Close();
            ValveInCold_item = GetItem(FiledName.ValveInCold); ValveInCold_item.Close();
            ValveInHot_item = GetItem(FiledName.ValveInHot); ValveInHot_item.Close();
            ValveIsobutene_item = GetItem(FiledName.ValveIsobutene); ValveIsobutene_item.Close();
            ValveICutoff_item = GetItem(FiledName.ValveICutoff); ValveICutoff_item.Open();
            ValveDischarge_item = GetItem(FiledName.ValveDischarge); ValveDischarge_item.Close();
            ValveStir_item = GetItem(FiledName.ValveStir); ValveStir_item.Close();
            ValveStop_item = GetItem(FiledName.ValveStop); ValveStop_item.Close();

            //管道
            FlowEmpty_item = GetItem(FiledName.FlowEmpty); FlowEmpty_item.Close();
            FlowInCold_item = GetItem(FiledName.FlowInCold); FlowInCold_item.Close();
            FlowInHot_item = GetItem(FiledName.FlowInHot); FlowInHot_item.Close();
            FlowInPhenol_item = GetItem(FiledName.FlowInPhenol); FlowInPhenol_item.Close();
            FlowIsObutene_item = GetItem(FiledName.FlowIsObutene); FlowIsObutene_item.Close();
            FlowInN2_item = GetItem(FiledName.FlowN2); FlowInN2_item.Close();
            FlowOutPhenol_item = GetItem(FiledName.FlowOutPhenol); FlowOutPhenol_item.Close();
            FlowOutSpices_item = GetItem(FiledName.FlowOutSpices); FlowOutSpices_item.Close();

            //label
            LabelLevel_item = GetItem(FiledName.LabelLevel); LabelLevel_item.Write(_phenol_value);
            LabelOxygen_item = GetItem(FiledName.LabelOxygen); LabelOxygen_item.Write(22);
            LabelPressure_item = GetItem(FiledName.LabelPressure); LabelPressure_item.Write(_pressure_value);
            LabelTemperature_item = GetItem(FiledName.LabelTemperature); LabelTemperature_item.Write(_temperature_value);
            LabelFlow_item = GetItem(FiledName.LabelFlow); LabelFlow_item.Write(0);

            //闪烁
            FlashCatalyst_item = GetItem(FiledName.FlashCatalyst); FlashCatalyst_item.Close();
            FlashStir_item = GetItem(FiledName.FlashStir); FlashStir_item.Close();
            FlashPressure_item = GetItem(FiledName.FlashPressure); FlashPressure_item.Close();
            FlashTemperature_item = GetItem(FiledName.FlashTemperature); FlashTemperature_item.Close();
            FlashWarning_item = GetItem(FiledName.FlashWarning);
            FlashWarning_item.Write(0);
        }
        private void ListenSignal()
        {
            Task t = new Task(() =>
            {
                while (!_listenCts.IsCancellationRequested)
                {
                    _valveInPhenol_State = Convert.ToInt32(ReadItem(FiledName.ValveInPhenol)) == open;
                    _valveOutPhenol_State = Convert.ToInt32(ReadItem(FiledName.ValveOutPhenol)) == open;
                    _valveN2_State = Convert.ToInt32(ReadItem(FiledName.ValveN2)) == open;
                    _valveEmpty_State = Convert.ToInt32(ReadItem(FiledName.ValveEmpty)) == open;
                    _valveAutoEmpty_State = Convert.ToInt32(ReadItem(FiledName.ValveAutoEmpty)) == open;
                    _valveInCold_State = Convert.ToInt32(ReadItem(FiledName.ValveInCold)) == open;
                    _valveInHot_State = Convert.ToInt32(ReadItem(FiledName.ValveInHot)) == open;
                    _valveIsobutene_State = Convert.ToInt32(ReadItem(FiledName.ValveIsobutene)) == open;
                    _valveICutoff_State = Convert.ToInt32(ReadItem(FiledName.ValveICutoff)) == open;
                    _valveDischarge_State = Convert.ToInt32(ReadItem(FiledName.ValveDischarge)) == open;
                    _valveStir_State = Convert.ToInt32(ReadItem(FiledName.ValveStir)) == open;
                    _valveStop_State = Convert.ToInt32(ReadItem(FiledName.ValveStop)) == open;

                    DateTime dtnow = DateTime.Now;
                    Step step = new Step()
                    {
                        Status =
                        {
                         { StatusName.液位, _phenol_value},
                         { StatusName.压力, _pressure_value},
                         { StatusName.温度, _temperature_value},
                         { StatusName.苯酚进料阀,Convert.ToInt32(ReadItem(FiledName.ValveInPhenol)) },
                         { StatusName.苯酚放料阀,Convert.ToInt32(ReadItem(FiledName.ValveOutPhenol)) },                         
                        { StatusName.自动放空阀,Convert.ToInt32(ReadItem(FiledName.ValveAutoEmpty))},
                        { StatusName.冷水阀,Convert.ToInt32(ReadItem(FiledName.ValveInCold))},
                        { StatusName.蒸汽阀,Convert.ToInt32(ReadItem(FiledName.ValveInHot))},
                        { StatusName.异丁烯阀,Convert.ToInt32(ReadItem(FiledName.ValveIsobutene))},
                        { StatusName.紧急切断阀,Convert.ToInt32(ReadItem(FiledName.ValveICutoff))},
                        { StatusName.放料阀,Convert.ToInt32(ReadItem(FiledName.ValveDischarge))},

                        { StatusName.氮气阀,-1},
                        { StatusName.放空阀,-1},
                        { StatusName.氮气阀2,-1},
                        { StatusName.放空阀2,-1},

                        { StatusName.搅拌阀,Convert.ToInt32(ReadItem(FiledName.ValveStir))},
                        },
                        Date = dtnow,

                    };
                    if (_replacecount == 1)
                    {
                        step.Status[StatusName.氮气阀] = Convert.ToInt32(ReadItem(FiledName.ValveN2));
                        if (_canopenempty)
                        {
                            if (_pressure_value == 0)
                            {
                                step.Status[StatusName.放空阀] = Convert.ToInt32(ReadItem(FiledName.ValveEmpty));
                                LabelOxygen_item.Write(5);
                                _replacecount = 2;
                                _canopenempty = false;
                            }
                        }
                    }
                    else if (_replacecount == 2)
                    {
                        step.Status[StatusName.氮气阀2] = Convert.ToInt32(ReadItem(FiledName.ValveN2));
                        if (_canopenempty)
                        {
                            step.Status[StatusName.放空阀2] = Convert.ToInt32(ReadItem(FiledName.ValveEmpty));
                            if (_pressure_value == 0)
                            {
                                LabelOxygen_item.Write(1);
                                _replacecount = 3;//3之后的放空
                                _isreplaceN2_over = true;
                            }

                        }
                    } 
                    _isListenSingnalover = true;
                    _steps.Add(step);
                    Thread.Sleep(500);
                }
            });
            t.Start();
        }

        #endregion

        #region 监听步骤，计分
        int _valveInPhenol = -1, _valveOutPhenol = -1, _valveAutoEmpty = -1, _valveInCold = -1,
                        _valveEmpty = -1, _valveN2 = -1,_valveInHot = 1, _valveIsobutene = -1,
                        _valveICutoff = -1, _valveDischarge = -1, _valveStir = -1, _valveStop = -1;

        private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                string temp = _serialPort.ReadLine();
                Console.WriteLine("收到：\t" + temp + DateTime.Now.ToString("t"));
                ParseSpData(temp);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
        }

        private void ParseSpData(string data)
        {
            #region 165
            Match match = Regex.Match(data, @"\d{5}_\d{3}");
            if (match.Success)
            {
                string s = match.Groups[0].Value.Split('_')[1];
                int v = Convert.ToInt32(s);
                string r = Convert.ToString(v, 2).PadLeft(8, '0');
                string first = match.Groups[0].Value.Split('_')[0];

                if (first == _prefix1)
                {

                    #region 21651

                    _valveAutoEmpty = Convert.ToInt32(r[0]);
                    _valveInPhenol = Convert.ToInt32(r[1]);
                    _valveStop = Convert.ToInt32(r[2]);
                    _valveStir = Convert.ToInt32(r[3]);
                    _valveOutPhenol = Convert.ToInt32(r[4]);
                    _valveEmpty = Convert.ToInt32(r[5]);
                    _valveInCold = Convert.ToInt32(r[6]);
                    _valveIsobutene = Convert.ToInt32(r[7]);

                    _valveInPhenol_State = _valveInPhenol == open;
                    _valveStop_State = _valveStop == open;
                    _valveStir_State = _valveStir == open;
                    _valveOutPhenol_State = _valveOutPhenol == open;
                    _valveEmpty_State = _valveEmpty == open;
                     _valveInCold_State = _valveInCold == open;
                    _valveIsobutene_State = _valveIsobutene == open;
                    _valveAutoEmpty_State = _valveAutoEmpty == open;

                    _isgetoverstate1 = true;

                    #endregion
                }
                else if (first == _prefix2)
                {

                    _valveInHot = Convert.ToInt32(r[0]);
                    _valveN2 = Convert.ToInt32(r[1]);
                    _valveDischarge = Convert.ToInt32(r[2]);
                    _valveICutoff = Convert.ToInt32(r[3]);

                    _valveInHot_State = _valveInHot == open;
                    _valveN2_State = _valveN2 == open;
                    _valveDischarge_State = _valveDischarge == open;
                    _valveICutoff_State = _valveICutoff == open;
                    _isgetoverstate2 = true;
                }

            } 
            #endregion

            #region 添加步骤

            DateTime dtnow = DateTime.Now;
            Step step = new Step()
            {
                Status =
                {
                    {StatusName.液位, _phenol_value},
                    {StatusName.压力, _pressure_value},
                    {StatusName.温度, _temperature_value},
                    {StatusName.苯酚进料阀, _valveInPhenol},
                    {StatusName.苯酚放料阀, _valveOutPhenol},
                    {StatusName.自动放空阀, _valveAutoEmpty},
                    {StatusName.冷水阀, _valveInCold},
                    {StatusName.蒸汽阀, _valveInHot},
                    {StatusName.异丁烯阀, _valveIsobutene},
                    {StatusName.紧急切断阀, _valveICutoff},
                    {StatusName.放料阀, _valveDischarge},
                    {StatusName.氮气阀, -1},
                    {StatusName.放空阀, -1},
                    {StatusName.氮气阀2, -1},
                    {StatusName.放空阀2, -1},
                    {StatusName.搅拌阀, _valveStir},
                },
                Date = dtnow,
            };
            FillStep(_valveEmpty, _valveN2, step);
            _steps.Add(step);

            #endregion
        }

        private void FillStep(int valveEmpty, int valveN2, Step step)
        {
            if (_replacecount == 1)
            {
                step.Status[StatusName.氮气阀] = valveN2;
                if (_canopenempty)
                {
                    if (_pressure_value == 0 && valveEmpty == open)
                    {
                        step.Status[StatusName.放空阀] = valveEmpty;
                        LabelOxygen_item.Write(5);
                        _replacecount = 2;
                        _canopenempty = false;
                    }
                }
            }
            else if (_replacecount == 2)
            {
                step.Status[StatusName.氮气阀2] = valveN2;
                if (_canopenempty)
                {
                    step.Status[StatusName.放空阀2] = valveEmpty;
                    if (_pressure_value == 0 && valveEmpty == open)
                    {
                        LabelOxygen_item.Write(1);
                        _replacecount = 3;//3之后的放空
                        _isreplaceN2_over = true;
                    }

                }
            }
        }


        private void ListenOPCRelation()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
            {
                #region 苯酚物进料
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveInPhenol_State)
                        {
                            if (!Isinner) ValveInPhenol_item.Open();
                            FlowInPhenol_item.StartFlow();
                            _phenol_value += _phenol_increment;
                            if (_phenol_value <= 600)
                            {
                                LabelLevel_item.Write(_phenol_value);
                                SPYWValue(_phenol_value);
                            }
                            else if (_phenol_value > 650)
                            {
                                AddCompose("苯酚物进料：液位高于650，未关闭苯酚物进料阀");
                                BeginWarning(WarningType.苯酚物液位过高);
                            }
                        }
                        else
                        {
                            if (!Isinner) ValveInPhenol_item.Close();
                            StopWarning(WarningType.苯酚物液位过高);
                            FlowInPhenol_item.StopFlow();
                            if (_phenol_value > 650)
                            {
                                _phenol_value = 600;
                                LabelLevel_item.Write(_phenol_value);
                                SPYWValue(_phenol_value);
                            }
                        }
                        Thread.Sleep(_sleepSlow);
                    }
                });
                #endregion

                #region 苯酚物放料
                Task.Run(
                    () =>
                    {
                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (_valveOutPhenol_State)
                            {
                                if (!Isinner) ValveOutPhenol_item.Open();
                                FlowOutPhenol_item.StartFlow();
                                _phenol_value -= _phenol_decrement;

                                if (_phenol_value < 30)
                                    _phenol_decrement = 5;
                                else
                                    _phenol_decrement = 10;

                                if (_phenol_value >= 0)
                                {
                                    LabelLevel_item.Write(_phenol_value);
                                    SPYWValue(_phenol_value);
                                }
                                else
                                {
                                    _phenol_value = 0;
                                    FlowOutPhenol_item.StopFlow();
                                }
                            }
                            else
                            {
                                if (!Isinner) ValveOutPhenol_item.Close();
                                FlowOutPhenol_item.StopFlow();
                            }
                            Thread.Sleep(_sleepSlow);
                        }
                    }
                    );
                #endregion

                #region 充氮气
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveN2_State)
                        {
                            _pressure_increment = 0.02;
                            if (!Isinner) ValveN2_item.Open();
                            FlowInN2_item.StartFlow();
                            _pressure_value += _pressure_increment;
                            _pressure_value = Math.Round(_pressure_value, 2);
                            LabelPressure_item.Write(_pressure_value);                            
                            SpPressureValue(_pressure_value);
                            if (_pressure_value > 0.3)
                            {
                                FlashPressure_item.StartFlow();
                                BeginWarning(WarningType.氮气置换压力过高);
                            }

                            if (_pressure_value > 0.2)
                                _canopenempty = true;
                        }
                        else
                        {
                            if (!Isinner) ValveN2_item.Close();
                            if (_pressure_value < 0.3)
                                StopWarning(WarningType.氮气置换压力过高);
                            FlowInN2_item.StopFlow();
                        }
                        Thread.Sleep(_sleepfast);
                    }
                });
                #endregion

                #region 放空
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveEmpty_State)
                        {
                            if (!Isinner) ValveEmpty_item.Open();
                            FlowEmpty_item.StartFlow();

                            _pressure_value = Math.Round(_pressure_value, 2);
                            _pressure_value -= _pressure_decrement;

                            _pressure_decrement = _pressure_value < 0.05 ? 0.01 : 0.04;

                            if (_pressure_value >= 0.01)
                            {
                                LabelPressure_item.Write(_pressure_value);                                
                                SpPressureValue(_pressure_value);
                            }
                            else
                            {
                                _pressure_value = 0;
                                LabelPressure_item.Write(_pressure_value);
                                FlashPressure_item.Close();

                            }
                        }
                        else
                        {
                            if (!Isinner) ValveEmpty_item.Close();
                            FlowEmpty_item.StopFlow();
                            FlashPressure_item.Close();
                        }
                        Thread.Sleep(_sleepfast);
                    }
                });
                #endregion

                int sleeplong = 800;
                #region 冷却水阀
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveInCold_State)
                        {
                            if (!Isinner) ValveInCold_item.Open();
                            FlowInCold_item.StartFlow();
                            _temperature_value = Math.Round(_temperature_value, 2);
                            _temperature_value -= _temperature_decrement;

                            if (_temperature_value < 20)
                            {
                                _temperature_decrement = 0;
                            }
                            else if (_temperature_value < 100)
                            {
                                _temperature_decrement = 2;
                                FlashTemperature_item.StopFlow();
                            }
                                
                            LabelTemperature_item.Write(_temperature_value);
                            SpTemperatureValue(_temperature_value);
                        }
                        else
                        {
                            if (!Isinner) ValveInCold_item.Close();
                            FlowInCold_item.StopFlow();
                        }
                        Thread.Sleep(sleeplong);
                    }
                });
                #endregion

                #region 蒸汽阀
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveInHot_State)
                        {
                            if (!Isinner) ValveInHot_item.Open();
                            FlowInHot_item.StartFlow();

                            //控制反应温度
                            if (_temperature_value >= 90)//100
                                _temperature_increment = 0;
                            else if (_temperature_value > 85)
                                _temperature_increment = 0.2;
                            else if (_temperature_value > 80)
                                _temperature_increment = 1;
                            else
                                _temperature_increment = 2;

                            if (_temperature_value <= 90)//100
                            {
                                _temperature_value = Math.Round(_temperature_value, 2);
                                _temperature_value += _temperature_increment;
                                LabelTemperature_item.Write(_temperature_value);
                                SpTemperatureValue(_temperature_value);
                            }
                        }
                        else
                        {
                            if (!Isinner) ValveInHot_item.Close();
                            FlowInHot_item.StopFlow();
                        }
                        Thread.Sleep(sleeplong);
                    }
                });
                #endregion

                #region 异丁烯阀 +
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveIsobutene_State)
                        {
                            if (!Isinner) ValveIsobutene_item.Open();
                            //if (!_isreplaceN2_over)
                            //{
                            //    this.Vetodown();
                            //}
                            _flow_value = Math.Round(_flow_value, 2);
                            LabelFlow_item.Write(_flow_value);
                            FlowIsObutene_item.StartFlow();

                            //控制反应压力
                            if (_pressure_value < 0.6)
                            {
                                _pressure_increment = 0.03;
                                _flow_crement = 1;
                            }
                            else if (_pressure_value > 0.6 && _pressure_value < 0.8)
                            {
                                _pressure_increment = 0.02;
                                _flow_crement = 0.5;
                            }
                            else
                            {
                                _pressure_increment = 0;
                                _flow_crement = 0;
                            }


                            if (_pressure_value <= 0.8)
                            {
                                _pressure_value += _pressure_increment;
                                _pressure_value = Math.Round(_pressure_value, 2);
                                SpPressureValue(_pressure_value);
                                LabelPressure_item.Write(_pressure_value);

                                if (_flow_value < 50)
                                {
                                    _flow_value += _flow_crement;
                                    SpFlowValue(_flow_value);
                                }
                            }
                            //泄露异常
                            if (_isleakAbnormal && _temperature_value >= 80)
                            {
                                BeginLeakAbnormal();
                            }
                        }
                        else
                        {
                            if (!Isinner) ValveIsobutene_item.Close();
                            LabelFlow_item.Write(0);
                            FlowIsObutene_item.StopFlow();
                        }
                        Thread.Sleep(_sleepfast);
                    }
                });
                #endregion

                #region 放料阀
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (_valveDischarge_State)
                        {
                            if (!Isinner) ValveDischarge_item.Open();
                            FlowOutSpices_item.StartFlow();
                        }
                        else
                        {
                            if (!Isinner) ValveDischarge_item.Close();
                            FlowOutSpices_item.StopFlow();
                        }
                        Thread.Sleep(_sleepfast);
                    }
                });
                #endregion

                #region 搅拌釜状态
                Task.Run(() =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        if (!_valveStir_State)
                        {
                            StopStir();
                            if (!Isinner)
                            {
                                ValveStir_item.Close();
                            }

                        }
                        else
                        {
                            if (!Isinner) ValveStir_item.Open();
                            FlashStir_item.Open();
                            Thread.Sleep(300);
                            FlashStir_item.Close();
                            Thread.Sleep(300);
                            BeginStir();

                        }
                        Thread.Sleep(_sleepfast);
                       
                    }
                });
                
                #endregion
                
            }));


        }

        void CalcFlowAndStep()
        {
            #region 计算流程 
            //进料
            var phenol_in_item = _steps.Where(i => i.Status[StatusName.苯酚进料阀] == open).OrderByDescending(i => i.Status[StatusName.液位]).ThenByDescending(i => i.Date).FirstOrDefault();

            //出料
            //var phenol_out_item = phenol_in_item != null ? _steps.Where(i => i.Status[StatusName.苯酚放料阀] == open 
            //    && i.Date > phenol_in_item.Date)
            //    .OrderBy(i => i.Status[StatusName.液位])
            //    .ThenByDescending(i => i.Date).FirstOrDefault() : null;
            var phenol_out_item = _steps.Where(i => i.Status[StatusName.苯酚放料阀] == open)
               .OrderBy(i => i.Status[StatusName.液位])
               .ThenByDescending(i => i.Date).FirstOrDefault();

            //氮气1
            //var n2_pressure_item1 = phenol_out_item != null ? _steps.Where(i => i.Status[StatusName.氮气阀] == open
            //    && i.Date > phenol_out_item.Date).OrderByDescending(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() : null;
            var n2_pressure_item1 = _steps.Where(i => i.Status[StatusName.氮气阀] == open).OrderByDescending(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault();

            //放空1
            var o2_pressure_item1=n2_pressure_item1!=null?_steps.Where(i => i.Status[StatusName.放空阀] == open && i.Date > n2_pressure_item1.Date)
                .OrderBy(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() : null;

            //氮气2
            var n2_pressure_item2 =o2_pressure_item1!=null?_steps.Where(i => i.Status[StatusName.氮气阀2] == open && i.Date > o2_pressure_item1.Date)
                .OrderByDescending(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() : null;

            //放空2
            var o2_pressure_item2=n2_pressure_item2!=null?_steps.Where(i => i.Status[StatusName.放空阀2] == open && i.Date > n2_pressure_item2.Date)
                .OrderBy(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() : null;

            //升温温度
            //var temperature_item = o2_pressure_item2 != null ? _steps.Where(i => i.Status[StatusName.蒸汽阀] == open && i.Date > o2_pressure_item2.Date)
            //    .OrderByDescending(i => i.Status[StatusName.温度]).ThenByDescending(i => i.Date).FirstOrDefault() : null;
            var temperature_item = _steps.Where(i => i.Status[StatusName.蒸汽阀] == open )
                .OrderByDescending(i => i.Status[StatusName.温度]).ThenByDescending(i => i.Date).FirstOrDefault() ;

            //异丁烯升压
            //var isobutene_item = o2_pressure_item2 != null ? _steps.Where(i => i.Status[StatusName.异丁烯阀] == open && i.Date > o2_pressure_item2.Date)
            //    .OrderByDescending(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() : null;
            var isobutene_item = _steps.Where(i => i.Status[StatusName.异丁烯阀] == open )
                .OrderByDescending(i => i.Status[StatusName.压力]).ThenByDescending(i => i.Date).FirstOrDefault() ;
           
            //冷水降温-升温之后
            //var cold_item =temperature_item!=null? _steps.Where(i => i.Status[StatusName.冷水阀] == open )
            //    .OrderBy(i => i.Status[StatusName.温度]).ThenByDescending(i => i.Date).FirstOrDefault():null;
            Step cold_item;
             cold_item = temperature_item != null ? _steps.Where(i => i.Status[StatusName.冷水阀] ==open)
                 .OrderBy(i => i.Status[StatusName.温度]).ThenByDescending(i => i.Date).FirstOrDefault() : null;

            //最后一步出料阀
            var discharge_count = cold_item != null ? _steps.Count(i => i.Status[StatusName.放料阀] == open && i.Date > cold_item.Date) : -1;
            var discharge_open_item = discharge_count > 0 ? _steps.Where(i => cold_item != null && (i.Status[StatusName.放料阀] == open && i.Date > cold_item.Date)).OrderBy(i => i.Date).FirstOrDefault() : null;

            //反应时一直开着    --计算 反应时间内关闭的次数，如果>0，则说明有关闭   ==0，则一直打开
            var stir_open_first = _steps.FirstOrDefault(i => i.Status[StatusName.搅拌阀] == open);//首次打开的时间
            var stir_close_count = cold_item != null ?
               _steps.Count(i => i.Status[StatusName.搅拌阀] == close
                   && stir_open_first != null && i.Date > stir_open_first.Date
                   && i.Date < cold_item.Date) : -1;


            //var stir_not_open_count = o2_pressure_item2 != null && cold_item!=null ? _steps.Count(i => i.Status[StatusName.搅拌阀] == close && i.Date > o2_pressure_item2.Date && i.Date < cold_item.Date) : -1;

            //出料之前关闭搅拌 -是否要加呢？    降温后-出料前  （出料前已经降温了）
            //var stir_close_count = discharge_open_item != null ? _steps.Count(i => i.Status[StatusName.放料阀] == close && i.Date < discharge_open_item.Date) : -1;

            //反应完- 降温前  要关闭蒸汽阀
            var hot_close_count = isobutene_item != null&&cold_item!=null ? _steps.Count(i => temperature_item != null && (i.Status[StatusName.蒸汽阀] == open && i.Date > temperature_item.Date && i.Date < cold_item.Date)) : -1;

            #endregion
            #region 计分
            //进料 
            if (phenol_in_item != null)
            {
                AddCompose(phenol_in_item.Status[StatusName.液位] > 400 ? "苯酚物进料：完成" : "苯酚物进料：液位低于400");
            }

            //出料
            if (phenol_out_item != null)
            {
                double phenol_in_level = phenol_in_item == null ? 450 : phenol_in_item.Status[StatusName.液位];

                var diff = phenol_in_level - phenol_out_item.Status[StatusName.液位];
                if (diff > 450)
                {
                    AddCompose("苯酚物放料：液位差高于450，通入苯酚物过量");
                }
                else if (diff >= 400 && diff <= 450)
                {
                    AddCompose("苯酚物放料：液位差400-450，完成");
                }
                else
                {
                    AddCompose("苯酚物放料：液位差低于400，原料不足");
                }
            }
            else
            {
                AddCompose("苯酚物放料：未操作");
                
            }

            //氮气置换1
            if (n2_pressure_item1 != null)
            {
                var pressure_value = n2_pressure_item1.Status[StatusName.压力];
                if (pressure_value > 0.3)
                    AddCompose(string.Format("第{0}次氮气置换：气压>0.3时未关闭氮气阀，压力过高", 1));
                else if (pressure_value >= 0.2 && pressure_value <= 0.3)
                    AddCompose(string.Format("第{0}次氮气置换：打开氮气阀，充氮气至0.2-0.3MPa", 1));
            }
            else
            {
                AddCompose(string.Format("第{0}次氮气置换：打开氮气阀，未操作", 1));
            }

            if (o2_pressure_item1 != null)
            {
                var pressure_value = o2_pressure_item1.Status[StatusName.压力];
                if (pressure_value <= 0.01 && pressure_value > -1)
                {
                    AddCompose(string.Format("第{0}次氮气置换：打开放空阀，降压至0MPa", 1));
                    AddCompose(string.Format("第{0}次氮气置换：完成", 1));
                }
            }
            else
            {
                AddCompose(string.Format("第{0}次氮气置换：打开放空阀，未操作", 1));
            }
            

            //氮气置换2
            if (n2_pressure_item2 != null)
            {
                var pressure_value = n2_pressure_item2.Status[StatusName.压力];
                if (pressure_value > 0.3)
                    AddCompose(string.Format("第{0}次氮气置换：气压>0.3时未关闭氮气阀，压力过高", 2));
                else if (pressure_value >= 0.2 && pressure_value <= 0.3)
                    AddCompose(string.Format("第{0}次氮气置换：打开氮气阀，充氮气至0.2-0.3MPa", 2));
            }
            else
            {
                AddCompose(string.Format("第{0}次氮气置换：打开氮气阀，未操作", 2));
            }

            if (o2_pressure_item2 != null)
            {
                var pressure_value = o2_pressure_item2.Status[StatusName.压力];
                if (pressure_value <= 0.01 && pressure_value > -1)
                {
                    AddCompose(string.Format("第{0}次氮气置换：打开放空阀，降压至0MPa", 2));
                    AddCompose(string.Format("第{0}次氮气置换：完成", 2));
                }
            }
            else
            {
                AddCompose(string.Format("第{0}次氮气置换：打开放空阀，未操作", 2));
                
            }

            //开搅拌
            if (stir_close_count == 0)
            {
                AddCompose("搅拌釜：打开");
            }
            else if (stir_close_count > 0)
            {
                AddCompose("反应过程中，关闭搅拌釜");
            }
            else if (stir_open_first == null)
            {
                AddCompose("搅拌釜：未打开");
            }

            //烷基化
            //打开蒸汽阀80-100得分
            bool isfillhot_over = false;
            bool isfillisobetene = false;
            if (temperature_item != null)
            {
                var temperature_value = temperature_item.Status[StatusName.温度];
                if ((isfillhot_over = temperature_value >= 80 && temperature_value <= 100))
                    AddCompose("烷基化：通入蒸汽使温度升至80℃，完成");
                else
                    AddCompose("烷基化：充蒸汽过程中，温度过低，关闭蒸汽阀");
            }
            else
            {
                AddCompose("烷基化：通入蒸汽使温度升至80℃，未完成");
            }
            
            //通入异丁烯
            if (isobutene_item != null)
            {
                var isobutene_pressure_value = isobutene_item.Status[StatusName.压力];
                if ((isfillisobetene = isobutene_pressure_value >= 0.6 && isobutene_pressure_value <= 0.8))
                {
                    AddCompose("烷基化：通入异丁烯使压力升至0.6MPa，完成");
                }
                else
                {
                    if (isobutene_pressure_value < 0.6)
                    {
                        AddCompose("烷基化：通入异丁烯过程中，异丁烯含量过低，关闭异丁烯进料阀");
                    }
                }
            }
            else
            {
                AddCompose("烷基化：通入异丁烯使压力升至0.6MPa，未完成");
            }
            

            //关闭蒸汽阀
            if (hot_close_count == 0)
            {
                AddCompose("烷基化：反应完成，关闭蒸汽阀");
            }
            else
            {
                AddCompose("烷基化：反应完成，未关闭蒸汽阀");
            }

            //冷水降温
            if (cold_item != null)
            {
                if (cold_item.Status[StatusName.温度] < 50)
                    AddCompose("降温：打开冷却水阀，降温至50℃以下，完成");
                else
                    AddCompose("降温：未降到50℃以下");
            }
            else
            {
                AddCompose("降温：打开冷却水阀，降温至50℃以下，未完成");
            }
            //TODO:关闭搅拌

            //出料
            if (discharge_count > 0)
            {
                AddCompose("出料：打开放料阀，完成");
            }
            else
            {
                AddCompose("出料：打开放料阀，未完成");
            }
            #endregion
        }

        
        private void ListenSerialPort()
        {
            string chkcmd_1 = _flowcommand.Items.SingleOrDefault(i => i.Name == "chkcmd1").Value; // "#RYW21651&";
            string chkcmd_2 = _flowcommand.Items.SingleOrDefault(i => i.Name == "chkcmd2").Value; //"#RYW21652&";



            Task listSerialPortState = new Task(
                () =>
                {
                    while (!_listenCts.IsCancellationRequested)
                    {
                        SendScannerCmd(chkcmd_1);
                        Thread.Sleep(200);
                        SendScannerCmd(chkcmd_2);
                        Thread.Sleep(200);
                    }
                   
                    
                });
            listSerialPortState.Start();
        }
        void SendScannerCmd(string cmd)
        {
            try
            {
                if (!_serialPort.IsOpen) return;
                lock (this)
                {
                    _serialPort.Write(cmd);
                }
            }
            catch (Exception)
            {
            }
        }
        #endregion

        #region 处理异常的方法
        
        #region 温度异常

        public override void TemperatureAbnormal()
        {
            _warningDicionary.Add(WarningType.温度异常, false);
            Task.Run(() =>
            {
                while (_temperature_value < 125)
                {
                    _temperature_value += 3;
                    LabelTemperature_item.Write(_temperature_value);
                    SpTemperatureValue(_temperature_value);
                    Thread.Sleep(_sleepfast);
                }
                BeginWarning(WarningType.温度异常);
                FlashTemperature_item.StartFlow();
                HandleTempretureAbnormal();
            });
        }

        private void HandleTempretureAbnormal()
        {
            Task.Run(
                () =>
                    {
                        Parallel.Invoke(CloseHotValve4TpAbnormal, OpenColdValve4TpAbnormal);
                        StopWarning(WarningType.温度异常);
                        _warningDicionary[WarningType.温度异常] = true;
                    });
        }

        private void OpenColdValve4TpAbnormal()
        {
            while (!_listenCts.IsCancellationRequested)
            {
                if (_temperature_value <= 50)
                {
                    AddCompose("处理温度异常：打开冷水阀");
                    break;
                }
                else
                {
                    AddCompose("处理温度异常：未打开冷水阀");
                }
                Thread.Sleep(_sleepfast);
            }
        }

        void CloseHotValve4TpAbnormal()
        {
            while (!_listenCts.IsCancellationRequested)
            {
                if (!_valveInHot_State)
                {
                    AddCompose("处理温度异常：关闭蒸汽阀");
                    break;
                }
                else
                {
                    AddCompose("处理温度异常：未关闭蒸汽阀");
                }
                Thread.Sleep(_sleepfast);
            }
        }


        #endregion

        #region 压力异常

        public override void PressureAbnormal()
        {
            _warningDicionary.Add(WarningType.压力异常, false);
            Task.Run(() =>
            {
                while (_pressure_value < 2.5)
                {
                    _pressure_value += 0.05;
                    LabelPressure_item.Write(_pressure_value);
                    SpPressureValue(_pressure_value);
                    Thread.Sleep(_sleepfast);
                }
                BeginWarning(WarningType.压力异常);
                FlashPressure_item.StartFlow();
                HandlePressureAbnormal();
            });
        }

        private void HandlePressureAbnormal()
        {
            Task.Run(
                () =>
                    {
                        Parallel.Invoke(this.OpenAirValve4PAbnormal, this.CloseIsobuteneValve4PAbnormal);
                        StopWarning(WarningType.压力异常);
                        _warningDicionary[WarningType.压力异常] = true;
                    });
        }

        private void CloseIsobuteneValve4PAbnormal()
        {
            while (!_listenCts.IsCancellationRequested)
            {
                if (!_valveIsobutene_State)
                {
                    AddCompose("处理压力异常：关闭异丁烯进料阀");
                    break;
                }
                else
                {
                    AddCompose("处理压力异常：未关闭异丁烯进料阀");
                }
                Thread.Sleep(_sleepfast);
            }
        }

        private void OpenAirValve4PAbnormal()
        {
            _pressure_decrement = 0.06;//加快降压
            //打开放空阀
            while (!_listenCts.IsCancellationRequested)//true
            {
                if (_valveEmpty_State)
                {
                    if (_pressure_value <= 0.01)
                    {
                        AddCompose("处理压力异常：打开放空阀");
                        break;
                    }
                    else
                    {
                        AddCompose("处理压力异常：未打开放空阀");
                    }
                }
                Thread.Sleep(_sleepfast);
            }
        }
        #endregion

        #region 泄漏
        void BeginLeakAbnormal()
        {
            _isleakAbnormal = false;
            BeginWarning(WarningType.泄漏);
            BeginLeak();
            _warningDicionary.Add(WarningType.泄漏, false);
            HandleLeakAbnormal();
        }

        private void HandleLeakAbnormal()
        {
            Parallel.Invoke(
                () =>
                    {
                        //打开急停按钮
                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (_valveStop_State)
                            {
                                AddCompose("处理泄漏异常：按下急停按钮");
                                break;
                            }
                            else
                            {
                                AddCompose("处理泄漏异常：未按下急停按钮");
                            }
                            Thread.Sleep(_sleepfast);
                        }
                    },
                //关闭蒸汽和异丁烯
                () =>
                    {

                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (!_valveInHot_State)
                            {
                                AddCompose("处理泄漏异常：关闭蒸汽阀");
                                break;
                            }
                            else
                            {
                                AddCompose("处理泄漏异常：未关闭蒸汽阀");
                            }
                            Thread.Sleep(_sleepfast);
                        }
                    },
                () =>
                    {
                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (!_valveIsobutene_State)
                            {
                                AddCompose("处理泄漏异常：关闭异丁烯进料阀");
                                break;
                            }
                            else
                            {
                                AddCompose("处理泄漏异常：未关闭异丁烯进料阀");
                            }
                            Thread.Sleep(_sleepfast);
                        }
                    });

            StopWarning(WarningType.泄漏);
            _warningDicionary[WarningType.泄漏] = true;
        }

        #endregion
        #endregion

        #region 重写公共方法

        public override void Begin()
        {
            _steps.Clear();
            if (IsExamSpeed)
                ListenOPCRelation(); //联动

        }

        bool _isListenSingnalover;
        public override async Task<string> CheckDefault()
        {
            bool isOvertime = false;
            var loop = 0;
            StringBuilder builder = new StringBuilder();
            await Task.Run(() =>
            {
                if (!Isinner)
                {
                    Thread.Sleep(2000);
                    while (!_isgetoverstate1 || !_isgetoverstate2)
                    {
                        Thread.Sleep(1000);
                        loop++;
                        if (loop > 30)
                        {
                            isOvertime = true;
                            break;
                        }
                    }
                }
                else
                {
                    while (!_isListenSingnalover)
                    {
                        Thread.Sleep(_sleepfast);
                    }
                }
                
                if (_valveInPhenol_State)
                    builder.AppendLine("苯酚进料阀未关闭");
                if (_valveOutPhenol_State)
                    builder.AppendLine("苯酚放料阀未关闭");
                if (_valveN2_State)
                    builder.AppendLine("氮气阀未关闭");
                if (!_valveEmpty_State)
                    builder.AppendLine("手动放空阀未打开");
                if (_valveAutoEmpty_State)
                    builder.AppendLine("自动放空阀未关闭");
                if (_valveInCold_State)
                    builder.AppendLine("冷水阀未关闭");
                if (_valveInHot_State)
                    builder.AppendLine("蒸汽阀未关闭");
                if (_valveIsobutene_State)
                    builder.AppendLine("异丁烯进料阀未关闭");
                if (!_valveICutoff_State)
                    builder.AppendLine("紧急切断阀未打开");
                if (_valveStir_State)
                    builder.AppendLine("搅拌按钮未关闭");
                if (_valveStop_State)
                    builder.AppendLine("急停按钮未关闭");
                if(_valveDischarge_State)
                    builder.AppendLine("反应釜底部出料阀未关闭");
            });
            await InitServerData();
            if (_details == null)
                builder.AppendLine("可能由于网络原因，导致获取数据失败，请点击\"确定\"按钮 尝试重新获取");

            if (!isOvertime) return builder.ToString();
            builder.Clear();
            builder.AppendLine("访问设备信号超时，请检查设备连接");


            return builder.ToString();

        }

        public override void Over()
        {
            Close();
            CalcFlowAndStep();
            Score = CalcScore();
            CloseAllRelay();
            Finish();
            
        }

        public override void Close()
        {
            this._listenCts.Cancel();
            if (_serialPort != null)
            {
                _serialPort.DataReceived -= _serialPort_DataReceived;
                _serialPort.Close();
            }
           
        }
        #endregion

        #region 私有方法

        protected override void Vetodown()
        {
            SendMessage("在含氧量不合格的情况下打开异丁烯进料阀，属于严重违规操作，停止考核！");
            _isvetodown = true;
            this._listenCts .Cancel();
        }

        #endregion


        #region 写串口数据
        void SpFlowValue(double value)
        {
            WriteFlowValue(_llcmd, 1, value);
            WriteAIvalue(_aicmd, 3, value);
        }

        void SpPressureValue(double value)
        {
            WritePressureValue(_ylcmd, value);
            WriteAIvalue(_aicmd, 1, value);
        }

        void SpTemperatureValue(double value)
        {
            WriteTemperatureValue(_wdcmd, value);
            WriteAIvalue(_aicmd, 2, value);
        }

        private void SPYWValue(double value)
        {
            if (Isinner) return;
            double write_value = 255*value/600;
            write_value = Math.Round(write_value, 0);
            string cmdvalue = write_value.ToString().PadLeft(3, '0');
            string cmd = string.Format(_ywcmd, cmdvalue);
            try
            {
                lock (this)
                {
                    //Thread.Sleep(120);
                    if (_serialPort.IsOpen)
                    {
                        _serialPort.Write(cmd);
                    }
                }
            }
            catch (Exception ex)
            {
                LogTool.WriteErrorLog(ex);
            }
            
            
        }

        #endregion

        #region 操作继电器
        /// <summary>
        /// 写继电器
        /// </summary>
        /// <param name="number">0-128， </param>
        void SPWriteTool(int number)
        {
            if (Isinner) return;
            WriteTool(_relaycmd, number);
        }
        /// <summary>
        /// 关闭所有继电器
        /// </summary>
        void CloseAllRelay()
        {
            SPWriteTool(0);
        }

        /// <summary>
        /// 开始预警
        /// </summary>
        /// <param name="type">预警类型</param>
        void BeginWarning(WarningType type)
        {
            if (!_warningtypes.Contains(type))
            {
                FlashWarning_item.Open();
                _warningtypes.Add(type);
                _relay_command = _relay_command | _warning1number;//响
                _relay_command = _relay_command | _warning2number;//亮
                SPWriteTool(_relay_command);
            }
        }

        void StopWarning(WarningType type)
        {
            if (_warningtypes.Contains(type))
            {
                FlashWarning_item.Close();
                _relay_command = (~_warning1number) & _relay_command;
                _relay_command = (~_warning2number) & _relay_command;
                SPWriteTool(_relay_command);
                _warningtypes.Remove(type);
            }
        }

        /// <summary>
        /// 开始泄漏
        /// </summary>
        void BeginLeak()
        {
            FlashWarning_item.Open();
            _relay_command = _relay_command | _fognumber;
            SPWriteTool(_relay_command);
            Thread.Sleep(500);
            StopLeak();

        }
        /// <summary>
        /// 停止泄漏
        /// </summary>
        void StopLeak()
        {
            FlashWarning_item.Close();
            _relay_command = _relay_command & (~_fognumber);
            SPWriteTool(_relay_command);
        }

        void BeginStir()
        {
            _relay_command = _relay_command | _stirnumber;
            SPWriteTool(_relay_command);
        }

        void StopStir()
        {
            _relay_command = _relay_command & (~_stirnumber);
            SPWriteTool(_relay_command);
        }
        #endregion

        #region 枚举
        enum FiledName
        {
            //开关
            ValveInPhenol, ValveOutPhenol, ValveN2, ValveEmpty, ValveAutoEmpty, ValveInCold, ValveInHot, ValveIsobutene, ValveICutoff, ValveDischarge, ValveStir,
            //管道
            FlowEmpty, FlowInCold, FlowInHot, FlowInPhenol, FlowIsObutene, FlowN2, FlowOutPhenol, FlowOutSpices, ValveStop,
            //label
            LabelLevel, LabelOxygen, LabelPressure, LabelTemperature, LabelFlow,
            //闪烁
            FlashCatalyst, FlashStir, FlashPressure, FlashTemperature,
            FlashWarning
        }

        enum WarningType
        {
            氮气置换压力过高,
            温度异常,
            压力异常,
            泄漏,
            反应釜压力过高,
            反应釜内丙烯含量过高,
            苯酚物液位过高,
            通入苯酚物过量,
        }

        enum StatusName
        {
            液位, 压力, 温度, 苯酚进料阀, 苯酚放料阀, 放空阀, 氮气阀, 自动放空阀, 冷水阀, 蒸汽阀, 异丁烯阀, 紧急切断阀, 放料阀, 搅拌阀, 放空阀2, 氮气阀2
        }
        #endregion

    }
}
